
#include "stdafx.h"
#include "resource.h"
#include "FolderDlg.h"
#include "ProjectPropertiesPages.h"
#include "AppWinMFC.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNCREATE(CProjectPropertiesPage1, CMFCPropertyPage)
IMPLEMENT_DYNCREATE(CProjectPropertiesPage2, CMFCPropertyPage)
IMPLEMENT_DYNCREATE(CProjectPropertiesPage3, CMFCPropertyPage)

static TCHAR BASED_CODE szSelectZipFilter[] = _T("Archive Files (*.zip)|*.zip||");
CString GlobalProjectDir;

CString GetDirectory(CWnd *parent, CString msg)
{
    CFolderDialog dlg(parent);
    LPCITEMIDLIST pidl = dlg.BrowseForFolder(msg, BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT);
    return dlg.GetPathName(pidl);
}
//------------------------------------------------------------------------------------
CString GetZipFile(CWnd *parent, CString msg)
{
	CFileDialog dOpenFile(true,0,0,OFN_FILEMUSTEXIST|OFN_NOCHANGEDIR,szSelectZipFilter,parent,0,true);
	if(dOpenFile.DoModal() == IDOK)
	{
	    return dOpenFile.GetPathName();
	}
	else 
        return _T("");
}
//------------------------------------------------------------------------------------
void ExAddString(CListBox *lbox,const CString &val, int data)
{
    int idx = lbox->AddString(val);
    lbox->SetItemData(idx,data);
    CClientDC dc(lbox);

    CFont *f = lbox->GetFont();
    dc.SelectObject(f);

    CSize sz = dc.GetTextExtent(val, val.GetLength());
    sz.cx += 6;
    int width = lbox->GetHorizontalExtent();
    if(sz.cx > width) 
        lbox->SetHorizontalExtent(sz.cx);
}
//------------------------------------------------------------------------------------
BOOL IsValidName(CString strName, CString strDisplayName, CString exkeys = _T(""))
{
    strName.Trim();
    int pos = 0;
    pos = strName.FindOneOf(_T("%\"<>#,?;") + exkeys);
    if(pos != -1)
    {
        CString msg;
        msg.Format(_T("%s can not contain (\"<>,\"#?;%s\")"),strDisplayName,exkeys);
        AfxMessageBox(msg,MB_OK);
        return FALSE;
    }
    
    if(strName.IsEmpty())
    {
        CString msg;
        msg.Format(_T("%s does not contain a valid value!"),strDisplayName);
        AfxMessageBox(msg,MB_OK);
        return FALSE;
    }
    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CProjectPropertiesPage1 property page

CProjectPropertiesPage1::CProjectPropertiesPage1() : CMFCPropertyPage(CProjectPropertiesPage1::IDD)
{
    m_ProjectOptions = 0;
}
//------------------------------------------------------------------------------------
CProjectPropertiesPage1::~CProjectPropertiesPage1()
{
}
//------------------------------------------------------------------------------------
void CProjectPropertiesPage1::DoDataExchange(CDataExchange* pDX)
{
    CMFCPropertyPage::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_PAGE1_PROJDIR, m_cProjectDir);
    DDX_Control(pDX, IDC_PAGE1_PROJNAME, m_cProjectName);
    DDX_Control(pDX, IDC_PAGE1_SCENEMANAGER, m_cSceneManager);
    DDX_Control(pDX, IDC_PAGE1_SCMCONFIGFILE, m_cSCMConfigFile);
    DDX_Control(pDX, IDC_PAGE1_SETPROJECTDIR, m_bSetProjDir);
    DDX_Control(pDX, IDC_PAGE1_ETLDIR, m_cETLDir);
    DDX_Control(pDX, IDC_PAGE1_HYDRAXDIR, m_cHydraxDir);
    DDX_Control(pDX, IDC_PAGE1_CAELUMDIR, m_cCaelumDir);
    DDX_Control(pDX, IDC_PAGE1_PGDIR, m_cPagedGeometryDir);
}
//------------------------------------------------------------------------------------
BOOL CProjectPropertiesPage1::OnInitDialog()
{
    CMFCPropertyPage::OnInitDialog();

    CString strTemp;
    if(m_ProjectOptions->IsNewProject)
    {
        strTemp = m_ProjectOptions->CreatedIn.c_str();
        m_cProjectDir.SetWindowText(strTemp);
    }
    else
    {
        strTemp = m_ProjectOptions->ProjectDir.c_str();
        m_cProjectDir.SetWindowText(strTemp);
        CStatic *cText = (CStatic*)GetDlgItem(IDC_STATIC2);
        cText->SetWindowText(_T("Project Directory"));
    }
    strTemp = m_ProjectOptions->ProjectName.c_str();
    m_cProjectName.SetWindowText(strTemp);
    strTemp = m_ProjectOptions->SceneManagerName.c_str();
    m_cSceneManager.SelectString(-1,strTemp);
    strTemp = m_ProjectOptions->ETLDirectory.c_str();
    m_cETLDir.SetWindowText(strTemp);
    strTemp = m_ProjectOptions->HydraxDirectory.c_str();
    m_cHydraxDir.SetWindowText(strTemp);
    strTemp = m_ProjectOptions->CaelumDirectory.c_str();
    m_cCaelumDir.SetWindowText(strTemp);
    strTemp = m_ProjectOptions->PagedGeometryDirectory.c_str();
    m_cPagedGeometryDir.SetWindowText(strTemp);
    strTemp = m_ProjectOptions->SceneManagerConfigFile.c_str();
    m_cSCMConfigFile.SetWindowText(strTemp);
  
    if(!m_ProjectOptions->IsNewProject)
    {
        m_cProjectDir.EnableWindow(0);
        m_cProjectName.EnableWindow(0);
        m_cSceneManager.EnableWindow(0);
        m_cETLDir.EnableWindow(0);
        m_cHydraxDir.EnableWindow(0);
        m_cCaelumDir.EnableWindow(0);
        m_cPagedGeometryDir.EnableWindow(0);
        m_cSCMConfigFile.EnableWindow(0);
    }
    return TRUE;
}
//------------------------------------------------------------------------------------
BEGIN_MESSAGE_MAP(CProjectPropertiesPage1, CMFCPropertyPage)
  ON_BN_CLICKED(IDC_PAGE1_SETPROJECTDIR, &CProjectPropertiesPage1::OnSetProjectDirClicked)
  ON_EN_CHANGE(IDC_PAGE1_PROJDIR, &CProjectPropertiesPage1::OnChange)
  ON_EN_CHANGE(IDC_PAGE1_PROJNAME, &CProjectPropertiesPage1::OnChange)
  ON_EN_CHANGE(IDC_PAGE1_SCENEMANAGER, &CProjectPropertiesPage1::OnChange)
  ON_EN_CHANGE(IDC_PAGE1_SCMCONFIGFILE, &CProjectPropertiesPage1::OnChange)
  ON_EN_CHANGE(IDC_PAGE1_ETLDIR, &CProjectPropertiesPage1::OnChange)
  ON_EN_CHANGE(IDC_PAGE1_HYDRAXDIR, &CProjectPropertiesPage1::OnChange)
  ON_EN_CHANGE(IDC_PAGE1_CAELUMDIR, &CProjectPropertiesPage1::OnChange)
  ON_EN_CHANGE(IDC_PAGE1_PGDIR, &CProjectPropertiesPage1::OnChange)
END_MESSAGE_MAP()
//------------------------------------------------------------------------------------

/////////////////////////////////////////////////////////////////////////////
// CProjectPropertiesPage2 property page

CProjectPropertiesPage2::CProjectPropertiesPage2() : CMFCPropertyPage(CProjectPropertiesPage2::IDD)
{
    m_ProjectOptions = 0;
    m_PopupMenu.LoadMenu(IDR_LOCATIONMENU);
}
//------------------------------------------------------------------------------------
CProjectPropertiesPage2::~CProjectPropertiesPage2()
{
}
//------------------------------------------------------------------------------------
void CProjectPropertiesPage2::DoDataExchange(CDataExchange* pDX)
{
    CMFCPropertyPage::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_PAGE2_RESOURCES, m_cResources);
}
//------------------------------------------------------------------------------------
BOOL CProjectPropertiesPage2::OnInitDialog()
{
    CMFCPropertyPage::OnInitDialog();

    CString value;
    unsigned int i;
    for(i = 0;i < m_ProjectOptions->ResourceDirectories.size();i++)
    {
	    value = m_ProjectOptions->ResourceDirectories[i].c_str();
	    value.Delete(0,3);
	    if(m_ProjectOptions->ResourceDirectories[i].find("FS:") == 0)
	        ExAddString(&m_cResources,value,1);
	    else if(m_ProjectOptions->ResourceDirectories[i].find("ZP:") == 0)
	        ExAddString(&m_cResources,value,2);
    }
    return TRUE;
}
//------------------------------------------------------------------------------------
void CProjectPropertiesPage2::OnContextMenu(CWnd* pWnd,CPoint pos)
{
    CRect rc;
    CMenu *pMenu = m_PopupMenu.GetSubMenu(0);
    CListBox *listbox = &m_cResources;
   
    listbox->GetWindowRect(&rc);
    if(!rc.PtInRect(pos))
    {
        listbox = NULL;
    }

    if(listbox)
    {
        CPoint savepos = pos;
	    BOOL isinside;
	    int selecteditem = -1;

	    if(listbox->GetCount() > 0)
	    {
	        listbox->SetFocus();
	        listbox->ScreenToClient(&pos);
	        selecteditem = listbox->ItemFromPoint(pos,isinside);
	        listbox->SetCurSel(selecteditem);
	        pMenu->EnableMenuItem(ID_PROJECTPROP_REMOVELOC,MF_ENABLED);
	    }
	    else 
	        pMenu->EnableMenuItem(ID_PROJECTPROP_REMOVELOC,MF_GRAYED);
		 
	    int ret = TrackPopupMenu( pMenu->m_hMenu,TPM_RETURNCMD | TPM_RIGHTBUTTON, savepos.x,savepos.y, 0, GetSafeHwnd(),NULL);
	    switch(ret)
	    {
	    case ID_PROJECTPROP_ADDDIR:
            {
                CString retVal = GetDirectory(this,_T("Select a Directory to Add..."));
				if(retVal != _T("")) 
				{
			        if(!m_ProjectOptions->IsNewProject)
				    {
				        retVal = GetRelativePath(GlobalProjectDir,retVal,false);
				        SetModified(TRUE);
				    }
				    ExAddString(listbox,retVal,1);
				}
                break;
			}
	    case ID_PROJECTPROP_ADDARCHIVE:
            {
                CString retVal = GetZipFile(this,_T("Select an Archive File"));
                if(retVal != _T(""))
				{
				    if(!m_ProjectOptions->IsNewProject)
				    {
				        retVal = GetRelativePath(GlobalProjectDir,retVal,true);
				        SetModified(TRUE);
				    }
				    ExAddString(listbox,retVal,2);
				}
                break;
			}
	    case ID_PROJECTPROP_REMOVELOC:
            {
                listbox->DeleteString(selecteditem);
	            if(!m_ProjectOptions->IsNewProject) 
                 SetModified(TRUE);  
	         break;
         }
	  }
   }
}

BEGIN_MESSAGE_MAP(CProjectPropertiesPage2, CMFCPropertyPage)
	ON_WM_CONTEXTMENU()
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CProjectPropertiesPage3 property page

CProjectPropertiesPage3::CProjectPropertiesPage3() : CMFCPropertyPage(CProjectPropertiesPage3::IDD)
{
    m_ProjectOptions = 0;
}
//------------------------------------------------------------------------------------
CProjectPropertiesPage3::~CProjectPropertiesPage3()
{
}
//------------------------------------------------------------------------------------
void CProjectPropertiesPage3::DoDataExchange(CDataExchange* pDX)
{
	CMFCPropertyPage::DoDataExchange(pDX);
}
//------------------------------------------------------------------------------------
BOOL CProjectPropertiesPage3::OnInitDialog()
{
    CMFCPropertyPage::OnInitDialog();
    return TRUE;
}
//------------------------------------------------------------------------------------
BEGIN_MESSAGE_MAP(CProjectPropertiesPage3, CMFCPropertyPage)
END_MESSAGE_MAP()
//------------------------------------------------------------------------------------
void CProjectPropertiesPage1::OnSetProjectDirClicked()
{
    CString path = GetDirectory(this,_T("Select Projects Folder"));
    if(!(path.IsEmpty())) 
        m_cProjectDir.SetWindowText(path);
}
//------------------------------------------------------------------------------------
void CProjectPropertiesPage1::OnChange()
{
    if(!m_ProjectOptions->IsNewProject) 
        SetModified(TRUE);
  
    TCHAR tmpstr[1000];
    CString CreatedIn;
    CString ProjectName;

    m_cProjectDir.GetWindowText(tmpstr,1000);
    CreatedIn = tmpstr;
    m_cProjectName.GetWindowText(tmpstr,1000);
    ProjectName = tmpstr;
    if(m_ProjectOptions->IsNewProject)
        GlobalProjectDir = CreatedIn + _T("\\") + ProjectName + _T("\\");
    else
        GlobalProjectDir = CreatedIn + _T("\\");
    CleanPath(GlobalProjectDir);
}
//------------------------------------------------------------------------------------
BOOL CProjectPropertiesPage1::OnApply()
{
    TCHAR tmpstr[1000];
    CString CreatedIn;
    CString ProjectDir; 
    CString ProjectName;
    CString SceneManagerName;
    CString ETLDir;
    CString HydraxDir;
    CString CaelumDir;
    CString PagedGeometryDir;

    if(!m_ProjectOptions->IsNewProject)  
        return CMFCPropertyPage::OnApply();

    m_cProjectDir.GetWindowText(tmpstr,1000);
    CreatedIn = tmpstr;
    m_cProjectName.GetWindowText(tmpstr,1000);
    ProjectName = tmpstr;
    m_cSceneManager.GetWindowText(tmpstr,1000);
    SceneManagerName = tmpstr;
    m_cETLDir.GetWindowText(tmpstr,1000);
    ETLDir = tmpstr;
    m_cHydraxDir.GetWindowText(tmpstr,1000);
    HydraxDir = tmpstr;
    m_cCaelumDir.GetWindowText(tmpstr,1000);
    CaelumDir = tmpstr;
    m_cPagedGeometryDir.GetWindowText(tmpstr,1000);
    PagedGeometryDir = tmpstr;

    if(!IsValidName(CreatedIn,_T("Project Directory")) && m_ProjectOptions->IsNewProject) 
        return FALSE;
    if(!IsValidName(ProjectName,_T("Project Name"),_T("\\/")))
        return FALSE;
    if(!IsValidName(ETLDir,_T("ETL Directory"))) 
        return FALSE;
    if(!IsValidName(HydraxDir,_T("Hydrax Directory"))) 
        return FALSE;
    if(!IsValidName(CaelumDir,_T("Caelum Directory"))) 
        return FALSE;
    if(!IsValidName(PagedGeometryDir,_T("Paged Geometry Directory"))) 
        return FALSE;
  
    TCHAR buffer1[1000];
    TCHAR buffer2[1000];
    TCHAR buffer3[1000];
    _tcscpy_s(buffer1,1000,ETLDir);
    _tcscpy_s(buffer2,1000,HydraxDir);
    _tcscpy_s(buffer3,1000,CaelumDir);

    if(PathStripToRoot(buffer1) || PathStripToRoot(buffer2) || PathStripToRoot(buffer3))
    {
        AfxMessageBox(_T("All ETL, Hydrax and Caelum Directories should be\nRelative to Project Directory!!\n(Sub Directories are recommended)"),MB_OK);
        return FALSE;
    }
  
    ProjectDir = GlobalProjectDir + _T("\\");
    CleanPath(ProjectDir);

    if(PathFileExists(ProjectDir) && AfxMessageBox(_T("Specified path already exists.\nDo you want to overwrite contents of the directory?"), MB_YESNO) == IDNO)
       return FALSE; 
  
    if(!MakeDirectory(ProjectDir)) 
        return FALSE;

    m_ProjectOptions->CreatedIn = ConvertToApoString(CreatedIn); 
    m_ProjectOptions->ProjectDir = ConvertToApoString(ProjectDir);
    m_ProjectOptions->ProjectName = ConvertToApoString(ProjectName);
    m_ProjectOptions->SceneManagerName = ConvertToApoString(SceneManagerName);
    m_cSCMConfigFile.GetWindowText(tmpstr,1000);
    m_ProjectOptions->SceneManagerConfigFile = ConvertToApoString(CString(tmpstr));
    m_ProjectOptions->ETLDirectory = ConvertToApoString(ETLDir);
    m_ProjectOptions->HydraxDirectory = ConvertToApoString(HydraxDir);
    m_ProjectOptions->CaelumDirectory = ConvertToApoString(CaelumDir);
    m_ProjectOptions->PagedGeometryDirectory = ConvertToApoString(PagedGeometryDir);

    return CMFCPropertyPage::OnApply();
}
//------------------------------------------------------------------------------------
BOOL CProjectPropertiesPage2::OnApply()
{
    m_ProjectOptions->ResourceDirectories.clear();

    CString strTemp;
    int stype;
    TCHAR buffer[1000];
    unsigned int i;
    unsigned int itemcount = m_cResources.GetCount();
    for(i = 0;i < itemcount;i++)
    {
	    m_cResources.GetText(i,buffer);
	    strTemp = buffer;
	    stype = m_cResources.GetItemData(i);
	    String val;
	    if(stype == 1)
	    {
	        if(m_ProjectOptions->IsNewProject) strTemp = GetRelativePath(GlobalProjectDir,strTemp,false);
	        val = ConvertToApoString(strTemp);
	        val = "FS:" + val;
	        m_ProjectOptions->ResourceDirectories.push_back(val);
	    }
	    else if(stype == 2)
	    {   
	        if(m_ProjectOptions->IsNewProject) strTemp = GetRelativePath(GlobalProjectDir,strTemp,false);
	        val = ConvertToApoString(strTemp);
            val = "ZP:" + val;
            m_ProjectOptions->ResourceDirectories.push_back(val);
	    }
    }

    return CMFCPropertyPage::OnApply();
}
//------------------------------------------------------------------------------------
BOOL CProjectPropertiesPage3::OnApply()
{
   return CMFCPropertyPage::OnApply();
}
//------------------------------------------------------------------------------------
